Skip to content

fix(server): classify ACP Task tool calls as collab agent tool calls - #8443

Open
NoahLinckeScout wants to merge 4 commits into
pingdotgg:mainfrom
NoahLinckeScout:fix/acp-task-tool-classification
Open

fix(server): classify ACP Task tool calls as collab agent tool calls#8443
NoahLinckeScout wants to merge 4 commits into
pingdotgg:mainfrom
NoahLinckeScout:fix/acp-task-tool-classification

Conversation

@NoahLinckeScout

@NoahLinckeScout NoahLinckeScout commented Aug 27, 2026

Copy link
Copy Markdown

What Changed

canonicalItemTypeFromAcpToolKind in AcpCoreRuntimeEvents.ts (the helper shared by the Cursor and Grok adapters) now recognises Task tool calls and classifies them collab_agent_tool_call instead of falling through to its dynamic_tool_call default.

A Task call is recognised by rawInput._toolName === "task" (case-insensitive) or a title matching /^task:/i. Every other kind is unchanged. One helper plus its single call site, and tests.

Why

A thread on an ACP-backed provider launched several subagents through its Task tool. All of them ran to completion. The timeline showed them as anonymous tool rows, indistinguishable from ordinary tool noise.

The launches are never dropped. Over ACP a Task launch arrives as a plain background tool call:

  • session/updatetool_call / tool_call_update, kind: "other"
  • title: "Task: ..."
  • rawInput: { _toolName: "task" }, rawOutput: { isBackground: true }

canonicalItemTypeFromAcpToolKind keys only off kind, and has no Task branch, so kind: "other" lands in the dynamic_tool_call default.

This is an inconsistency between adapters, not a new policy. Every other adapter already classifies the same work as collab_agent_tool_call:

  • ClaudeAdapter.classifyToolItemTypenormalized === "task" || normalized.includes("agent") || ...
  • OpenCodeAdapternormalized.includes("task") || normalized.includes("agent") || ...
  • CodexAdaptertype.includes("collab")

The shared ACP helper was the only one without it, so Cursor and Grok were the odd ones out. This brings them in line.

Repro: start a thread on an ACP-backed provider (Cursor or Grok), ask it to delegate something via its Task tool, and watch the timeline. Before this change the launches render with the generic tool icon; projection_thread_activities shows tool.completed rows with itemType: dynamic_tool_call and a Task: ... summary.

Known limitation

ACP carries no model, agent type, or subagent prompt for these calls, so per-subagent attribution still is not possible for these providers. The row now at least reports that it was agent work.

UI Changes

No UI code is touched, but the reclassification does change how these rows render, via two existing call sites:

  • MessagesTimeline.tsx:2475 — icon goes from hammer (dynamic_tool_call) to bot (collab_agent_tool_call)
  • MessagesTimeline.logic.ts:413 — group summary kind goes from dynamic-tool to agent-tool

I have not attached before/after screenshots: reproducing the row requires a live Cursor or Grok session that actually delegates through its Task tool, which I could not capture cleanly. The rendering delta above is the whole of the visible change, and it comes entirely from those two existing branches rather than from anything in this diff. Happy to add screenshots if you want them before reviewing.

Tests

Added to the existing AcpCoreRuntimeEvents.test.ts: three Task spellings (both recognizers, plus one with no title) assert collab_agent_tool_call, with negative controls (_toolName: "mcp__x"dynamic_tool_call, kind: "search"web_search) so the new branch cannot swallow unrelated calls.

Verified red/green rather than assuming: with the call site reverted to canonicalItemTypeFromAcpToolKind, the new test fails with expected collab_agent_tool_call, received dynamic_tool_call; with the fix it passes.

Verified locally:

  • vp test run src/provider/acp/AcpCoreRuntimeEvents.test.ts → 4 passed
  • full apps/server suite → 245 files passed, 2816 passed / 10 skipped (baseline on this commit's parent: 245 files, 2815 passed)
  • vp run typecheck → exit 0
  • vp fmt --check → clean; vp lint reports nothing new for the changed files

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes — see the UI Changes section; the rendering delta is described precisely, but I could not capture live screenshots
  • I included a video for animation/interaction changes (n/a)

Note

Low Risk
Narrow classification and presentation change for a specific tool shape; downstream impact is showing agent work correctly rather than altering auth or data paths.

Overview
ACP Task tool launches from Cursor/Grok were emitted as generic dynamic_tool_call rows because classification only looked at tool kind. The server now detects Task calls (rawInput._toolName case-insensitively or a task: title) and emits collab_agent_tool_call, aligning ACP with other adapters.

On mobile, work-log icons follow that type: collab_agent_tool_call and task rows with a taskId use the agent icon instead of the hammer; dynamic_tool_call stays hammer. Error tone still maps to alert so failed delegated tasks stay visibly failed.

Tests cover ACP classification (including negatives) and the mobile icon rules.

Reviewed by Cursor Bugbot for commit 24764ff. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Classify ACP Task tool calls as collab_agent_tool_call in event mapper and mobile icon logic

  • ACP tool calls detected as Task tools (via rawInput._toolName == "task" or title starting with task:) now emit itemType collab_agent_tool_call instead of the kind-based classification in AcpCoreRuntimeEvents.ts.
  • The mobile workEntryIcon util in threadActivity.ts now returns the agent icon for collab_agent_tool_call entries and any entry carrying a taskId; entries with error tone still return alert.
  • Behavioral Change: collab_agent_tool_call entries that previously showed the hammer icon now show agent; dynamic_tool_call still maps to hammer.

Macroscope summarized 24764ff.

A thread on an ACP-backed provider that launched subagents via its Task tool
showed zero subagents in the UI. The launches were never dropped: over ACP they
arrive as ordinary background tool calls titled "Task: ..." with
`rawInput._toolName === "task"` and no agent identity on the wire, so
`canonicalItemTypeFromAcpToolKind` filed them under its `dynamic_tool_call`
default. Every consumer that makes delegated work visible keys off
`collab_agent_tool_call`, so the rows sat in the timeline as anonymous tool noise.

The other adapters already classify the same work as `collab_agent_tool_call`
(`ClaudeAdapter.classifyToolItemType`, `OpenCodeAdapter`, `CodexAdapter`), so the
shared ACP helper was the outlier. Recognize the Task spellings there so the ACP
providers get the same classification: `rawInput._toolName === "task"`
(case-insensitive) or a title matching `/^task:/i`. All other kinds are unchanged.

Identity limits remain: ACP carries no model, agent type, or subagent prompt for
these calls, so per-subagent attribution is still not possible. The row now at
least reports that it was agent work.
@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 545d6093-b5be-4f63-ad98-6439f9b78434

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 27, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c5af99eea9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/server/src/provider/acp/AcpCoreRuntimeEvents.ts
@macroscopeapp

macroscopeapp Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 24764ff

Macroscope's review found this PR approvable — This is a localized classification and UI-rendering fix for existing ACP Task events, with unrelated tool handling preserved and targeted regression tests added. It introduces no schema, deployment, security, or workflow changes.

You can add or adjust custom eligibility rules. Learn more.

…c tools

Review on pingdotgg#8443 noted that reclassified ACP Task launches were still invisible
on mobile: the work-log icon derivation filed  beside
 under the same hammer, the only presentation branch for
either type. Right — the server change gave web bot styling and agent grouping,
and mobile still showed anonymous tool noise.

The icon now reads the collab type (or a task id) as agent work, matching how
the web timeline classifies the same rows as . Other tool kinds
keep their existing icons.

Verified: apps/mobile suite 112 files passed, 765 tests passed. Server ACP
classification tests still pass. Typecheck exit 0. The new test fails against
the pre-fix hammer grouping.
…c tools

Review on pingdotgg#8443 noted that reclassified ACP Task launches were still invisible
on mobile: the work-log icon derivation filed collab_agent_tool_call beside
dynamic_tool_call under the same hammer, the only presentation branch for
either type. Right — the server change gave web bot styling and agent grouping,
and mobile still showed anonymous tool noise.

The icon now reads the collab type (or a task id) as agent work, matching how
the web timeline classifies the same rows as agent-tool. Other tool kinds
keep their existing icons.

Verified: apps/mobile suite 112 files passed, 765 tests passed. Server ACP
classification tests still pass. Typecheck exit 0. The new test fails against
the pre-fix hammer grouping.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6b64534. Configure here.

Comment thread apps/mobile/src/lib/threadActivity.ts
Cursor Bugbot on the previous commit: the collab-agent branch ran before the
error-tone branch, so a failed task.completed or terminal task.updated with a
taskId rendered as agent instead of alert. Mobile has one icon where web
overlays failure after selection, so nested-agent failures lost their only
destructive signal.

The error tone now wins above the agent branch. Added the failing-then-passing
test: a failed collab_agent_tool_call with a taskId keeps the alert icon.

Verified: apps/mobile suite 112 files passed, 766 tests passed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant